package com.example.f2fboottest.controller;

import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.example.f2fboottest.config.Configs;
import com.example.f2fboottest.model.ExtendParams;
import com.example.f2fboottest.model.GoodsDetail;
import com.example.f2fboottest.model.builder.AlipayTradePrecreateRequestBuilder;
import com.example.f2fboottest.model.builder.AlipayTradeQueryRequestBuilder;
import com.example.f2fboottest.model.builder.AlipayTradeRefundRequestBuilder;
import com.example.f2fboottest.model.result.AlipayF2FPrecreateResult;
import com.example.f2fboottest.model.result.AlipayF2FQueryResult;
import com.example.f2fboottest.model.result.AlipayF2FRefundResult;
import com.example.f2fboottest.service.AlipayTradeService;
import com.example.f2fboottest.service.impl.AlipayTradeServiceImpl;
import com.example.f2fboottest.util.ZxingUtils;
import com.fasterxml.jackson.databind.util.ClassUtil;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dadaguai
 * @date 2022/3/26 19:36
 */
@Controller

public class F2fcontroller {

    @PostMapping("/pay")
    //必填项                    唯一订单号，         商品标题（暂定为模板标题）,总金额       ，优惠金额
    public String getpreCreat(String outTradeNo, String subject, String totalAmount, String undiscountableAmount, Model model, HttpServletRequest request) {
        Configs.init("zfbinfo.properties");
        AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
        model.addAttribute("outTradeNo", outTradeNo);
        model.addAttribute("subject", subject);
        model.addAttribute("totalAmount", totalAmount);
        model.addAttribute("undiscountableAmount", undiscountableAmount);
//        // (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
//        // 需保证商户系统端不能重复，建议通过数据库sequence生成，
//        String outTradeNo = request.getParameter("outTradeNo");
//          outTradeNo="20";
//        // (必填) 订单标题，粗略描述用户的支付目的。如“喜士多（浦东店）消费”
//        String subject = request.getParameter("subject");
//           subject="模板1";
//        // (必填) 订单总金额，单位为元，不能超过1亿元
//        // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
//        String totalAmount = request.getParameter("totalAmount");
//           totalAmount="30";
//        // (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
//        // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
//        String undiscountableAmount = request.getParameter("undiscountableAmount");
//          undiscountableAmount="5";
        // 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
        // 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
        String sellerId = "";

        // 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
        String body = "购买商品2件共15.00元";

        // 商户操作员编号，添加此参数可以为商户操作员做销售统计
        String operatorId = "test_operator_id";

        // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
        String storeId = "test_store_id";

        // 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，详情请咨询支付宝技术支持
        ExtendParams extendParams = new ExtendParams();
        extendParams.setSysServiceProviderId("2088100200300400500");

        // 支付超时，定义为120分钟
        String timeoutExpress = "120m";
        // 商品明细列表，需填写购买商品详细信息，
        List<GoodsDetail> goodsDetailList = new ArrayList<GoodsDetail>();
        // 创建一个商品信息，参数含义分别为商品id（使用国标）、名称、单价（单位为分）、数量，如果需要添加商品类别，详见GoodsDetail
        GoodsDetail goods1 = GoodsDetail.newInstance("goods_id001", "全麦小面包", 1500, 1);
        // 创建好一个商品后添加至商品明细列表
        goodsDetailList.add(goods1);

        // 继续创建并添加第一条商品信息，用户购买的产品为“黑人牙刷”，单价为5.05元，购买了两件
        GoodsDetail goods2 = GoodsDetail.newInstance("goods_id002", "黑人牙刷", 505, 2);
        goodsDetailList.add(goods2);

        // AlipayTradePrecreateContentBuilder builder = new AlipayTradePrecreateContentBuilder()
        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject)
                .setTotalAmount(totalAmount)
                .setOutTradeNo(outTradeNo)
                .setUndiscountableAmount(undiscountableAmount)
                .setSellerId(sellerId)
                .setBody(body)
                .setOperatorId(operatorId)
                .setStoreId(storeId)
                .setExtendParams(extendParams)
                .setTimeoutExpress(timeoutExpress)
//              .setNotifyUrl("http://www.test-notify-url.com")//支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                .setGoodsDetailList(goodsDetailList);
        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                System.out.println("支付宝预下单成功: )");

                AlipayTradePrecreateResponse res = result.getResponse();
//                ClassPathResource classPathResource=new ClassPathResource("/static/");
                String basePath = request.getServletContext().getRealPath("/");
                basePath = ClassUtils.getDefaultClassLoader().getResource("").getPath();
                basePath += "static/";
                String fileName = String.format("images%sqr-%s.png", File.separator, res.getOutTradeNo());
                String filePath = new StringBuilder(basePath).append(fileName).toString();
                System.out.println("filePath");
//                out.println("<img src=\"" + fileName + "\" />");
//                out.println("filePath:" + filePath);
                ZxingUtils.getQRCodeImge(res.getQrCode(), 256, filePath);
                System.out.println(filePath);
                model.addAttribute("fileName", fileName);
                break;

            case FAILED:
                System.out.println("支付宝预下单失败!!!");
                break;

            case UNKNOWN:
                System.out.println("系统异常，预下单状态未知!!!");
                break;

            default:
                System.out.println("不支持的交易状态，交易返回异常!!!");
                break;
        }
        System.out.println(result.getResponse().getBody());
        return "test";
    }

    @PostMapping("/tradequery")
    @ResponseBody
    //订单号必填
    public String QueryOrderDetail(String outTradeNo){
        // 一定要在创建AlipayTradeService之前设置参数
        Configs.init("zfbinfo.properties");
        AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
//        // (必填) 商户订单号，通过此商户订单号查询当面付的交易状态
//        String outTradeNo = request.getParameter("outTradeNo");
        AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
                .setOutTradeNo(outTradeNo);
        AlipayF2FQueryResult result = tradeService.queryTradeResult(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                System.out.println("查询返回该订单支付成功: )");

                AlipayTradeQueryResponse resp = result.getResponse();

                System.out.println(resp.getTradeStatus());
                System.out.println(resp.getFundBillList());
                break;

            case FAILED:
                System.out.println("查询返回该订单支付失败!!!");
                break;

            case UNKNOWN:
                System.out.println("系统异常，订单支付状态未知!!!");
                break;

            default:
                System.out.println("不支持的交易状态，交易返回异常!!!");
                break;
        }
        return result.getResponse().getBody();
    }

    @PostMapping("/refound")
    @ResponseBody
    //                             订单号            退款金额              凭证号                退款原因             商户id测试版不用填写（需要去支付宝申请门店）
    public  String Traderefound(String outTradeNo,String refundAmount,String outRequestNo,String refundReason,String storeId){
        // 一定要在创建AlipayTradeService之前设置参数
        Configs.init("zfbinfo.properties");
        AlipayTradeService tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
//        // (必填) 外部订单号，需要退款交易的商户外部订单号
//        String outTradeNo = request.getParameter("outTradeNo");
//
//        // (必填) 退款金额，该金额必须小于等于订单的支付金额，单位为元
//        String refundAmount = request.getParameter("refundAmount");
//
//        // (可选，需要支持重复退货时必填) 商户退款请求号，相同支付宝交易号下的不同退款请求号对应同一笔交易的不同退款申请，
//        // 对于相同支付宝交易号下多笔相同商户退款请求号的退款交易，支付宝只会进行一次退款
//        String outRequestNo = request.getParameter("outRequestNo");
//
//        // (必填) 退款原因，可以说明用户退款原因，方便为商家后台提供统计
//        String refundReason = request.getParameter("refundReason");
//
//        // (必填) 商户门店编号，退款情况下可以为商家后台提供退款权限判定和统计等作用，详询支付宝技术支持
//        String storeId = request.getParameter("storeId");

        AlipayTradeRefundRequestBuilder builder = new AlipayTradeRefundRequestBuilder()
                .setOutTradeNo(outTradeNo)
                .setRefundAmount(refundAmount)
                .setRefundReason(refundReason)
                .setOutRequestNo(outRequestNo)
                .setStoreId(storeId);
        AlipayF2FRefundResult result = tradeService.tradeRefund(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                System.out.println("支付宝退款成功: )");
                break;

            case FAILED:
                System.out.println("支付宝退款失败!!!");
                break;

            case UNKNOWN:
                System.out.println("系统异常，订单退款状态未知!!!");
                break;

            default:
                System.out.println("不支持的交易状态，交易返回异常!!!");
                break;
        }
        return result.getResponse().getBody();
    }

}
